home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-05-01 | 12.3 KB | 428 lines | [TEXT/MPS ] |
- // USynchScroller.cp
- // Copyright © 1989-1991 by Apple Computer Inc. All rights reserved.
-
- #ifndef __UGEOMETRY__
- #include <UGeometry.h>
- #endif
-
- #ifndef __ULIST__
- #include <UList.h>
- #endif
-
- #ifndef __UEVENT__
- #include <UEvent.h>
- #endif
-
- #ifndef __UCOMMAND__
- #include <UCommand.h>
- #endif
-
- #ifndef __UDOCUMENT__
- #include <UDocument.h>
- #endif
-
- #ifndef __UWINDOW__
- #include <UWindow.h>
- #endif
-
- #ifndef __UFAILURE__
- #include <UFailure.h>
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include <UMacAppUtilities.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __UPATCH__
- #include <UPatch.h>
- #endif
-
- #ifndef __UMACAPPGLOBALS__
- #include <UMacAppGlobals.h>
- #endif
-
- #ifndef __STDLIB__
- #include "StdLib.h"
- #endif
-
- #ifndef __UITERATOR__
- #include "UIterator.h"
- #endif
-
- #ifndef __USYNCHSCROLLER__
- #include <USynchScroller.h>
- #endif
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollInit
-
- pascal void InitUSynchScroller(void)
- {
- if (qTemplateViews)
- {
- // Suppress Linker dead-stripping of these classes
- if (gDeadStripSuppression)
- {
- DontDeadStrip(TSynchScroller);
- DontDeadStrip(TPrimaryScroller);
- DontDeadStrip(TSecondaryScroller);
- }
- }
- }
-
- //****************************************************************************************
- // T S y n c h S c r o l l e r
- //****************************************************************************************
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TSynchScroller::Initialize(void) // override
-
- {
- inherited::Initialize();
- fLimiting = FALSE;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TSynchScroller::IRes(TDocument* itsDocument,
- TView* itsSuperview,
- Ptr& itsParams)// override
- {
- inherited::IRes(itsDocument, itsSuperview, itsParams);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TSynchScroller::SetScrollLimits(const VPoint& scrollLimit,
- Boolean drawScrollBars)// override
- {
- Boolean wasLimiting = fLimiting;
- FailInfo fi;
-
- VOLATILE(wasLimiting);
-
- fLimiting = TRUE;
- if (fi.Try())
- {
- inherited::SetScrollLimits(scrollLimit, drawScrollBars);
- fi.Success();
- }
- else // Recover
- {
- fLimiting = wasLimiting;
- fi.ReSignal();
- }
- fLimiting = wasLimiting;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollFields
-
- pascal void TSynchScroller::Fields(TObject* obj)// override
- {
- obj->DoToField("TSynchScroller", (Ptr)NULL, bClass);
- obj->DoToField("fLimiting", (Ptr) & fLimiting, bBoolean);
- inherited::Fields(obj);
- }
-
- //****************************************************************************************
- // T P r i m a r y S c r o l l e r
- //****************************************************************************************
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TPrimaryScroller::Initialize(void) // override
- {
- inherited::Initialize();
- fSecondaryScrollers = NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TPrimaryScroller::IRes(TDocument* itsDocument,
- TView* itsSuperview,
- Ptr& itsParams)// override
- {
- inherited::IRes(itsDocument, itsSuperview, itsParams);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TPrimaryScroller::Free(void) // override
-
- {
- fSecondaryScrollers = (TList *)FreeIfObject(fSecondaryScrollers);
- inherited::Free();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TPrimaryScroller::AddSecondaryScroller(TSecondaryScroller* itsSecondaryScroller,
- VCoordinate itsHDependency,
- VCoordinate itsVDependency)
- {
- if (itsSecondaryScroller)
- {
- // !!! Really should give notification by something like BeWithPrimaryScroller.
- itsSecondaryScroller->fPrimaryScroller = this;
- itsSecondaryScroller->fDeltaFactor = Point((short)itsVDependency, (short)itsHDependency); // long coerced to short
-
- if (!fSecondaryScrollers)
- fSecondaryScrollers = NewList();
-
- fSecondaryScrollers->Insert(itsSecondaryScroller);
-
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TPrimaryScroller::RemoveSecondaryScroller(TSecondaryScroller* itsSecondaryScroller)
- {
- if (itsSecondaryScroller)
- {
- // !!! Really should give notification by something like BeInPrimaryScroller.
- itsSecondaryScroller->fPrimaryScroller = NULL;
- if (fSecondaryScrollers)
- {
- fSecondaryScrollers->Delete(itsSecondaryScroller);
- // !!! TViews should be this nice with subview lists
- if (fSecondaryScrollers->IsEmpty())
- fSecondaryScrollers = (TList *)FreeIfObject(fSecondaryScrollers);
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TPrimaryScroller::DoScroll(const VPoint& delta,
- Boolean redraw)// override
- {
-
- // If invoked by SetScrollLimits, don't affect peer scrollers
- if (!fLimiting)
- {
- CObjectIterator iter(fSecondaryScrollers);
- TSecondaryScroller* aSecondaryScroller;
-
- for (aSecondaryScroller = (TSecondaryScroller*) iter.FirstObject(); iter.More(); aSecondaryScroller = (TSecondaryScroller*) iter.NextObject())
- {
- VPoint itsDelta(delta);
-
- for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
- if (aSecondaryScroller->fDeltaFactor[vhs]) // kVDependent or kHDependent
- {
- if (itsDelta[vhs] < 0)
- {
- // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
- long temp = Max(itsDelta[vhs], -aSecondaryScroller->fTranslation[vhs]);
- itsDelta[vhs] = temp;
- }
- else if (itsDelta[vhs] > 0)
- {
- // !!!FIX the following 2 lines after MPW C compiler bug is corrected.
- long temp1 = Min(itsDelta[vhs], aSecondaryScroller->fMaxTranslation[vhs] - aSecondaryScroller->fTranslation[vhs]);
- itsDelta[vhs] = temp1;
- }
- aSecondaryScroller->fTranslation[vhs] += itsDelta[vhs];
- }
-
- if (itsDelta != gZeroVPt)
- {
- aSecondaryScroller->InvalidateFocus(); // You never know who might call
- aSecondaryScroller->UpdateCoordinates();
- }
- }
- }
-
- inherited::DoScroll(delta, redraw);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TPrimaryScroller::ScrollDraw(const VPoint& delta,
- Boolean invalidate)// override
- {
- if (fSuperView->IsDrawable())
- {
- Rect superVisRect;
- VRect myVFrame;
- Rect myQDFrame;
- RgnHandle scrollRgn;
- FailInfo fi;
-
- VOLATILE(scrollRgn);
-
- if (fi.Try())
- {
- scrollRgn = MakeNewRgn();
-
- this->GetFrame(myVFrame);
- fSuperView->ViewToQDRect(myVFrame, myQDFrame);
- RectRgn(scrollRgn, myQDFrame);
-
- fSuperView->GetDrawableQDRect(superVisRect);
-
- if (gIntenseDebugging)
- WriteFocus();
-
- // Too far to use ScrollRect
- if ((labs(delta.h) > kMaxCoord) || (labs(delta.v) > kMaxCoord))
- {
- this->ForceRedraw();
-
- CObjectIterator iter(fSecondaryScrollers);
- TSecondaryScroller* aScroller;
-
- for (aScroller = (TSecondaryScroller*) iter.FirstObject(); iter.More(); aScroller = (TSecondaryScroller*) iter.NextObject())
- {
- if (delta.v && (aScroller->fDeltaFactor.v == kVDependent))
- aScroller->ForceRedraw();
- else if (delta.h && (aScroller->fDeltaFactor.h == kHDependent))
- aScroller->ForceRedraw();
- }
- }
- else // Can use ScrollRect
- {
- #if qDebug
- UseTempRgn2("TPrimaryScroller.ScrollDraw");
- #endif
- if (qDebug)
- fSuperView->AssumeFocused();
-
- CObjectIterator iter(fSecondaryScrollers);
- TSecondaryScroller* aScroller;
-
- for (aScroller = (TSecondaryScroller*) iter.FirstObject(); iter.More(); aScroller = (TSecondaryScroller*) iter.NextObject())
- {
- VRect frameVRect;
- Rect frameRect;
- Point localDeltaFactor = aScroller->fDeltaFactor;
-
- // !!! with additional tests we could also support scrollers in other superviews
- // and non-matching extents and scrollLimits in the pertinent axis by simply calling
- // their scrolling methods. This would be nice for synchronized windows.
- aScroller->GetFrame(frameVRect);
- aScroller->fSuperView->ViewToQDRect(frameVRect, frameRect);
- // main scroller is moving both directions but dependent can only move in v
- if (delta.h && delta.v && (localDeltaFactor.h == kNotHDependent) && (localDeltaFactor.v == kVDependent))
- {
- ScrollRect(frameRect, 0, (short) - delta.v, gTempRgn2);
- aScroller->fSuperView->InvalidateRgn(gTempRgn2);
- }
- // main scroller is moving both directions but dependent can only move in h
- else if (delta.h && delta.v && (localDeltaFactor.h == kHDependent) && (localDeltaFactor.v == kNotVDependent))
- {
- ScrollRect(frameRect, (short) - delta.h, 0, gTempRgn2);
- aScroller->fSuperView->InvalidateRgn(gTempRgn2);
- }
- // main scroller is moving in either direction and dependent can follow
- else if ((delta.h && (localDeltaFactor.h == kHDependent)) || (delta.v && (localDeltaFactor.v == kVDependent)))
- {
- RectRgn(gTempRgn2, frameRect);
- UnionRgn(scrollRgn, gTempRgn2, scrollRgn);
- }
- }
-
- if (qDebug)
- fSuperView->AssumeFocused();
-
- // Now, we've either scrolled any dependent scrollers that can't scroll with
- // us or we've accumulated their frames in scrollRgn. By clipping to the
- // accumulated region we can just scroll the entire superview and the right
- // stuff should happen. (Cross fingers)
- SectRgn(scrollRgn, qd.thePort->clipRgn, scrollRgn);
-
- // Get clip so we can restore it later and keep from having
- // to invalidate the superview's focus
- GetClip(gTempRgn2);
-
- SetClip(scrollRgn);
- ScrollRect(superVisRect, (short) - delta.h, (short) - delta.v, scrollRgn);
-
- // restore the clip so we don't have to invalidate the focus
- SetClip(gTempRgn2);
-
- fSuperView->InvalidateRgn(scrollRgn);
- #if qDebug
- DoneWithTempRgn2();
- #endif
- }
- scrollRgn = DisposeIfRgnHandle(scrollRgn);
- fi.Success();
- }
- else // Recover
- {
- scrollRgn = DisposeIfRgnHandle(scrollRgn);
- fi.ReSignal();
- }
- if (!invalidate)
- fSuperView->Update();
- }
- }
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollFields
-
- pascal void TPrimaryScroller::Fields(TObject* obj)// override
- {
- obj->DoToField("TPrimaryScroller", (Ptr)NULL, bClass);
- obj->DoToField("fSecondaryScrollers", (Ptr) & fSecondaryScrollers, bObject);
- inherited::Fields(obj);
- }
-
- //****************************************************************************************
- // T S e c o n d a r y S c r o l l e r
- //****************************************************************************************
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TSecondaryScroller::Initialize(void)// override
-
- {
- inherited::Initialize();
- fPrimaryScroller = NULL;
- fDeltaFactor.h = kNotHDependent;
- fDeltaFactor.v = kNotVDependent;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollRes
-
- pascal void TSecondaryScroller::DoScroll(const VPoint& delta,
- Boolean redraw)// override
- {
- // Invoked by SetScrollLimits, so don't affect peer scrollers
- if (fLimiting)
- inherited::DoScroll(delta, redraw);
- else
- fPrimaryScroller->ScrollBy(VPoint(fDeltaFactor.v * delta.v, fDeltaFactor.h * delta.h), redraw);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment SyncScrollFields
-
- pascal void TSecondaryScroller::Fields(TObject* obj)// override
- {
- obj->DoToField("TSecondaryScroller", (Ptr)NULL, bClass);
- obj->DoToField("fPrimaryScroller", (Ptr) & fPrimaryScroller, bObject);
- obj->DoToField("fDeltaFactor", (Ptr) & fDeltaFactor, bPoint);
- inherited::Fields(obj);
- }
-
-
-